/**
 * 
 */

package com.pp.admin.main.client.tab.objectpages;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RadioButton;
import com.pp.admin.common.client.beans.Email;
import com.pp.admin.common.client.helper.AdminFlexTable;
import com.pp.admin.common.client.helper.AdminFormTextBox;
import com.pp.admin.common.client.helper.Resource;

/**
 * @author pandurang
 */
public class EmailInfo extends AdminFlexTable {

	static final int EMAIL_INFO_LBL_ROW = 0;

	static final int REQ_EMAIL_ROW = 1;

	static final int NO_TABLE_COLS = 4;

	static final int RADIO_GRP_COL = 0;

	static final int LABEL_COL = 1;

	static final int FIELD_COL = 2;

	static final int ADD_REMOVE_COL = 3;

	private Image addLink = new Image(Resource.ADD_IMG_URL);

	private int noOfEmails = 0;

	private EmailNode firstNode = null;

	private EmailNode lastNode = null;

	private int currentAddLinkRow = REQ_EMAIL_ROW;

	private static final int MAX_EMAIL_LMT = 4;

	private static final int MIN_EMAIL_LMT = 1;

	static final String MY_EMAIL_GRP = "emailGroup";

	class RemoveHandler implements ClickHandler {

		private EmailNode node = null;

		RemoveHandler(EmailNode node) {

			this.node = node;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt
		 * .event.dom.client. ClickEvent)
		 */
		@Override
		public void onClick(ClickEvent event) {

			removePhone(node);
		}

	}

	public EmailInfo(List<Email> emails) {
		init();
		if (emails.size() == 0) {
			addEmail(null);
		} else {
			Email email = null;
			for (Iterator<Email> iterator = emails.iterator(); iterator
					.hasNext();) {
				email = iterator.next();
				addEmail(email);
			}
		}
	}

	public EmailInfo() {
		init();
		addEmail(null);
	}

	public void init() {

		this.setWidget(EMAIL_INFO_LBL_ROW, LABEL_COL, new Label(myConstants
				.emailinfo()
				+ " : "));
		this.setTdAttribute(EMAIL_INFO_LBL_ROW, LABEL_COL,
				AdminFlexTable.ATR_TD_COLSPAN, "" + NO_TABLE_COLS);
		this.setWidget(currentAddLinkRow, ADD_REMOVE_COL, addLink);
		addLink.setHeight(Resource.ACTION_IMG_HIGHT);
		addLink.setWidth(Resource.ACTION_IMG_WIDTH);
		addLink.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {

				addEmail(null);
			}
		});
	}

	private void addEmail(Email email) {

		this.insertRow(currentAddLinkRow);
		EmailNode node = null;
		if (email == null) {
			node = new EmailNode(currentAddLinkRow, this);
		} else {
			node = new EmailNode(currentAddLinkRow, this, email);
		}
		this.setWidget(currentAddLinkRow, RADIO_GRP_COL, node.getSelected());
		this.setWidget(currentAddLinkRow, LABEL_COL, new Label(myConstants
				.email()
				+ " : "));
		this.getCellFormatter().setHorizontalAlignment(currentAddLinkRow,
				LABEL_COL, HasHorizontalAlignment.ALIGN_RIGHT);
		this.setWidget(currentAddLinkRow, FIELD_COL, node.getEmailFiled());
		if (firstNode == null) {
			firstNode = lastNode = node;
			node.getSelected().setValue(true);
		} else {
			lastNode.setNext(node);
			lastNode = node;
			this.setWidget(currentAddLinkRow, ADD_REMOVE_COL, node
					.getRemoveLink());
		}
		currentAddLinkRow++;
		noOfEmails++;
		if (noOfEmails == MAX_EMAIL_LMT) {
			addLink.setVisible(false);
		}
	}

	private void removePhone(EmailNode node) {

		if (noOfEmails != MIN_EMAIL_LMT) {

			removeRow(node.getRowNo());

			EmailNode prev = node.getPrev();
			EmailNode next = node.getNext();
			if (prev == null && next == null) {
				firstNode = lastNode = null;
			} else if (prev == null && next != null) {
				firstNode = next;
				next.getSelected().setValue(true);
			} else if (next == null && prev != null) {
				lastNode = prev;
			}
			node.remove();
			currentAddLinkRow--;
			if (noOfEmails == MAX_EMAIL_LMT) {
				addLink.setVisible(true);
			}
			noOfEmails--;
		}
	}

	public List<Email> getEmailList() {

		List<Email> list = new ArrayList<Email>();
		EmailNode node = firstNode;
		while (node != null) {
			list.add(node.getEmail());
			node = node.getNext();
		}
		return list;
	}
}

class EmailNode {

	private EmailInfo parent = null;

	private Email email = new Email();

	private int rowNo;

	private AdminFormTextBox emailFiled = new AdminFormTextBox();

	private Image removeLink = new Image(Resource.REMOVE_IMG_URL);

	private RadioButton selected = new RadioButton(EmailInfo.MY_EMAIL_GRP);

	private EmailNode next = null;

	private EmailNode prev = null;

	public EmailNode(int rowNo, EmailInfo parent, Email email) {
		this(rowNo, parent);
		this.email = email;
		emailFiled.setText(email.getEmailId());
		if (email.isPrimary()) {
			selected.setValue(true);
		}
	}

	public EmailNode(int rowNo, EmailInfo parent) {

		this.parent = parent;
		this.rowNo = rowNo;
		removeLink.setHeight(Resource.ACTION_IMG_HIGHT);
		removeLink.setWidth(Resource.ACTION_IMG_WIDTH);
		removeLink.addClickHandler(parent.new RemoveHandler(this));
	}

	public Email getEmail() {

		email.setEmailId(emailFiled.getTextBox().getText());
		email.setPrimary(selected.getValue());
		return email;
	}

	public void remove() {

		if (prev != null) {
			prev.setNext(next);
		} else if (next != null) {
			next.setPrev(prev);
		}
		if (next != null) {
			next.slideUp();
		}
	}

	public void slideUp() {

		rowNo--;
		if (next != null) {
			next.slideUp();
		}
	}

	/**
	 * @return the emailFiled
	 */
	public AdminFormTextBox getEmailFiled() {

		return emailFiled;
	}

	/**
	 * @param emailFiled
	 *            the emailFiled to set
	 */
	public void setEmailFiled(AdminFormTextBox emailFiled) {

		this.emailFiled = emailFiled;
	}

	/**
	 * @return the removeLink
	 */
	public Image getRemoveLink() {

		return removeLink;
	}

	/**
	 * @param removeLink
	 *            the removeLink to set
	 */
	public void setRemoveLink(Image removeLink) {

		this.removeLink = removeLink;
	}

	/**
	 * @return the selected
	 */
	public RadioButton getSelected() {

		return selected;
	}

	/**
	 * @param selected
	 *            the selected to set
	 */
	public void setSelected(RadioButton selected) {

		this.selected = selected;
	}

	/**
	 * @return the next
	 */
	public EmailNode getNext() {

		return next;
	}

	/**
	 * @param next
	 *            the next to set
	 */
	public void setNext(EmailNode next) {

		this.next = next;
		if (next != null) {
			next.setPrev(this);
		}
	}

	/**
	 * @return the prev
	 */
	public EmailNode getPrev() {

		return prev;
	}

	/**
	 * @param prev
	 *            the prev to set
	 */
	public void setPrev(EmailNode prev) {

		this.prev = prev;
	}

	/**
	 * @return the rowNo
	 */
	public int getRowNo() {

		return rowNo;
	}
}
